package com.example.base_kotlin_xml.view

import android.net.Uri
import androidx.core.os.bundleOf
import androidx.fragment.app.viewModels
import androidx.navigation.fragment.navArgs
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ViewUtils
import com.example.base_kotlin_xml.R
import com.example.base_kotlin_xml.databinding.FragmentNetworkBinding
import com.example.base_kotlin_xml.model.NetworkIntent
import com.example.base_kotlin_xml.model.NetworkViewModel
import com.example.base_model.bean.BaseHttpPageBean
import com.example.base_model.bean.SearchBean
import com.example.base_model.bean.general.DataMergeBean
import com.example.base_model.bean.general.TestRequest
import com.example.base_model.ext.castTo
import com.example.base_model.ext.castToListOf
import com.example.base_model.ext.castToMap
import com.example.base_model.ext.whenStatus
import com.example.base_model.network.download.DownloadManager
import com.example.base_model.network.load.LoadingStrategy
import com.example.base_model.network.request_param.RequestParamInterface
import com.example.base_model.network.result.BaseResult
import com.example.base_model.view.BaseFragment
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map

/**
 * @Author: jiangKunKun
 * @CreateDate: 2025/7/30
 * @Description: 网络
 * @SpittingGrooves
 */
@AndroidEntryPoint
class NetworkFragment : BaseFragment<FragmentNetworkBinding>() {

    val vModel: NetworkViewModel by viewModels()

    override fun initObservers() {
        launchAndCollect {
            vModel.uiState
                .map { it.isLoading(LoadingStrategy.MAIN) } // 使用枚举检查状态
                .distinctUntilChanged()
                .collectLatest { isLoading ->
                    if (isLoading) {
                        showLoading("加载中...")
                    } else {
                        LogUtils.d("isLoading 关闭")
                        hideLoading()
                    }
                }
        }
        launchAndCollect {
            // 监听 aisleCodeResult 的变化
            vModel.uiState
                .map { it.aisleCodeResult } // 1. 只关心 aisleCodeResult
                .distinctUntilChanged()     // 2. 只有当它变化时才发射
                .collectLatest { result ->        // 3. 这里的 result 就是 BaseResult<String>
                    handleTest1(result)
                }
        }

        launchAndCollect {
            // 监听 searchResult 的变化
            vModel.uiState
                .map { it.searchResult }
                .distinctUntilChanged()
                .collectLatest { result ->
                    handleTest2(result)
                }
        }

        launchAndCollect {
            // 监听 dataMergeBeanState 的变化
            vModel.uiState
                .map { it.dataMergeBeanState }
                .distinctUntilChanged()
                .collectLatest { result ->
                    handleTest3(result)
                }
        }

        launchAndCollect {
            // 监听 dataMergeBeanStateTwo 的变化
            vModel.uiState
                .map { it.dataMergeBeanStateTwo }
                .distinctUntilChanged()
                .collectLatest { result ->
                    handleTest4(result)
                }
        }
        // 下载
        launchAndCollect{
            vModel.downloadState.collectLatest { status ->
                when (status) {
                    is DownloadManager.DownloadStatus.IDLE -> {
                        LogUtils.d("文件下载", "默认状态")
                    }
                    is DownloadManager.DownloadStatus.Started -> {
                        LogUtils.d("文件下载", "开始下载")
                        showLoading("开始下载...")
                    }
                    is DownloadManager.DownloadStatus.Progress -> {
                        LogUtils.d("文件下载", "下载进度: ${status.progress}%")

                    }
                    is DownloadManager.DownloadStatus.Success -> {
                        LogUtils.d("文件下载", "下载成功! Uri: ${status.fileUri}" +
                                (status.filePath?.let { "\n路径: $it" } ?: ""))
                        scanUriToMedia(status.fileUri)
                    }
                    is DownloadManager.DownloadStatus.Failed -> {
                        LogUtils.d("文件下载", "下载失败: ${status.error}")
                    }
                    is DownloadManager.DownloadStatus.Finished -> {
                        LogUtils.d("文件下载", "下载完成")
                        // 下载完成后的处理
                        hideLoading()
                    }
                }
            }
        }
    }

    private fun handleTest4(it: BaseResult<DataMergeBean>) {
        it.status.whenStatus(
            idle = {
                LogUtils.d("请求结果 合并数据 默认状态")
            },
            start = {
                showLoading("接口请求Loading测试...")
                LogUtils.d("请求结果 合并数据 开始状态")
            },
            dataSuccess = {
                LogUtils.d("请求结果 合并数据 成功状态", it.data)
            },
            dataFail = {
                val param = it.requestParam
                if (param is RequestParamInterface) {
                    // 处理 List<Bean>
                    param.castToListOf<TestRequest> { list ->
                        list.forEach { it ->
                            LogUtils.d("castToListOf 成功: ${it.name}, ${it.password}")
                        }
                    }

                    // 处理 Map
                    param.castToMap { map ->
                        LogUtils.d("原始 Map 参数: $map")
                        LogUtils.d("code 值: ${map["code"]}")
                        LogUtils.d("str 值: ${map["str"]}")
                    }

                    // 处理单个 Bean
                    param.castTo<TestRequest> { bean ->
                        LogUtils.d("castTo 成功: ${bean.name}, ${bean.password}")
                    }
                }
                LogUtils.d("请求结果 合并数据 失败状态", it.code, it.msg, it.requestParam)
            },
            error = {
                LogUtils.d("请求结果 合并数据 错误状态", it.code, it.msg)
            },
            finish = {
                ViewUtils.runOnUiThreadDelayed({
                    hideLoading()
                }, 1000)
                LogUtils.d("请求结果 合并数据 结束状态")
            }
        )
    }

    private fun handleTest3(it: BaseResult<String>) {
        it.status.whenStatus(
            idle = {
                LogUtils.d("请求结果 合并数据 默认状态")
            },
            start = {
                showLoading("接口请求Loading测试...")
                LogUtils.d("请求结果 合并数据 开始状态")
            },
            dataSuccess = {
                LogUtils.d("请求结果 合并数据 成功状态", it.data)
            },
            dataFail = {
                val param = it.requestParam
                if (param is RequestParamInterface) {
                    // 处理 List<Bean>
                    param.castToListOf<TestRequest> { list ->
                        list.forEach { it ->
                            LogUtils.d("castToListOf 成功: ${it.name}, ${it.password}")
                        }
                    }

                    // 处理 Map
                    param.castToMap { map ->
                        LogUtils.d("原始 Map 参数: $map")
                        LogUtils.d("code 值: ${map["code"]}")
                        LogUtils.d("str 值: ${map["str"]}")
                    }

                    // 处理单个 Bean
                    param.castTo<TestRequest> { bean ->
                        LogUtils.d("castTo 成功: ${bean.name}, ${bean.password}")
                    }
                }
                LogUtils.d("请求结果 合并数据 失败状态", it.code, it.msg, it.requestParam)
            },
            error = {
                LogUtils.d("请求结果 合并数据 错误状态", it.code, it.msg)
            },
            finish = {
                ViewUtils.runOnUiThreadDelayed({
                    hideLoading()
                }, 1000)
                LogUtils.d("请求结果 合并数据 结束状态")
            }
        )
    }

    private fun handleTest2(it: BaseResult<BaseHttpPageBean<SearchBean>>) {

        it.status.whenStatus(
            idle = {
                LogUtils.d("请求结果 搜索 默认状态")
            },
            start = {
                showLoading("接口请求Loading测试...")
                LogUtils.d("请求结果 搜索 开始状态")
            },
            dataSuccess = {
                LogUtils.d("请求结果 搜索 成功状态", it.data)
            },
            finish = {
                hideLoading()
            }
        )
    }


    /**
     * handleTest1
     */
    private fun handleTest1(it: BaseResult<String>) {
        it.status.whenStatus(
            idle = {
                LogUtils.d("请求结果 默认状态")
            },
            start = {
                LogUtils.d("请求结果 开始状态")
            },
            dataSuccess = {
                LogUtils.d("请求结果 成功状态", it.data)
            },
            dataFail = {
                val param = it.requestParam
                if (param is RequestParamInterface) {
                    // 处理 List<Bean>
                    param.castToListOf<TestRequest> { list ->
                        list.forEach { it ->
                            LogUtils.d("castToListOf 成功: ${it.name}, ${it.password}")
                        }
                    }

                    // 处理 Map
                    param.castToMap { map ->
                        LogUtils.d("原始 Map 参数: $map")
                        LogUtils.d("code 值: ${map["code"]}")
                        LogUtils.d("str 值: ${map["str"]}")
                    }

                    // 处理单个 Bean
                    param.castTo<TestRequest> { bean ->
                        LogUtils.d("castTo 成功: ${bean.name}, ${bean.password}")
                    }
                }
                LogUtils.d("请求结果 失败状态", it.code, it.msg, it.requestParam)
            },
            error = {
                LogUtils.d("请求结果 错误状态", it.code, it.msg)
            },
            finish = {
                LogUtils.d("请求结果 结束状态")
            }
        )
    }
    private fun scanUriToMedia(uri: Uri) {
        // 对于 MediaStore 创建的文件，系统通常会自动索引。
        // 对于旧版本Android创建的 file:// Uri，这个扫描仍然有用。
        // 你也可以选择性地只对 file:// Uri 调用它。
        LogUtils.d("MediaScan", "Scanning URI: $uri")
        android.media.MediaScannerConnection.scanFile(
            activity,
            arrayOf(uri.toString()), // MediaScannerConnection 现在可以更好地处理内容Uris
            null // MIME类型可以为null，让扫描器自己确定
        ) { path, scannedUri ->
            LogUtils.d("MediaScan", "Scan completed. Path: $path, Uri: $scannedUri")
        }
    }


    override fun initClickEvents() {
        // 网络1
        mBinding.btnNetwork1.setOnClickListener {
            vModel.processIntent(NetworkIntent.Test1("123", "456")) }
        // 网络2

        mBinding.btnNetwork2.setOnClickListener {
            vModel.processIntent(NetworkIntent.Test2("123")) }
        // 网络3
        mBinding.btnNetwork3.setOnClickListener {
            vModel.processIntent(NetworkIntent.Test3("123")) }
        // 网络4
        mBinding.btnNetwork4.setOnClickListener {
            vModel.processIntent(NetworkIntent.Test4("123")) }
        // 下载文件
        mBinding.btnNetworkDown.setOnClickListener {
//            val downloadUrl = "https://zhidao.baidu.com/question/380798177731958844.html"
            val downloadUrl = "https://upload-images.jianshu.io/upload_images/5809200-a99419bb94924e6d.jpg"
            // 方式1: 使用系统图片目录
            val baseDir = activity?.applicationContext?.getExternalFilesDir(android.os.Environment.DIRECTORY_PICTURES)?.absolutePath
                ?: activity?.applicationContext?.filesDir?.absolutePath

            // 使用系统的公共图片目录
            val picturesDir = android.os.Environment.getExternalStoragePublicDirectory(
                android.os.Environment.DIRECTORY_PICTURES
            ).absolutePath

            // 使用系统的公共DCIM目录（相机照片目录）
            val dcimDir = android.os.Environment.getExternalStoragePublicDirectory(
                android.os.Environment.DIRECTORY_DCIM
            ).absolutePath

            // 添加自定义子目录
            val subDir = "temp" // 可以根据需要修改
            val destinationPath = "$dcimDir/$subDir"


            val fileName = "下载图片测试.jpg"


            vModel.processIntent(NetworkIntent.DownloadFile(mActivity,downloadUrl, destinationPath, fileName))
        }
    }
    // Safe Args 自动生成的参数访问器
    private val args: NetworkFragmentArgs by navArgs()
    override fun initData() {
        LogUtils.d("userId: ${args.userId}",
            "userName: ${args.userName}",
            "isActive: ${args.isActive}",
            "userinfo: ${args.userInfo}",
            "tags: ${args.tags.toList()}",
            "scores: ${args.scores.toList()}",
            "friendList: ${args.friendList.toList()}")

    }

    override fun onBackPress() {
        val resultBundle = bundleOf(
            "network_result" to "网络请求完成页面的返回结果",
            "user_id" to args.userId
        )
        parentFragmentManager.setFragmentResult("from_network_fragment", resultBundle)
        LogUtils.d("返回结果按钮", "user_id: ${args.userId}")
        super.onBackPress()
    }



    override fun attachLayoutRes(): Int = R.layout.fragment_network
}